//@author A0100617W
#include "TimeParser.h"


TimeParser::TimeParser(void)
{
}


TimeParser::~TimeParser(void)
{
}

//@author A0100617W
std::string TimeParser::clear_Space_Punctuation(std::string s){
	size_t pos1 = s.find_first_not_of(NOT_FOUND_STRING);
	size_t pos2 = s.find_last_not_of(NOT_FOUND_STRING);

	if(pos1 == std::string::npos){
		return QUOTE;
	}

	return s.substr(pos1, pos2-pos1+1);
}


//@author A0100617W
std::string TimeParser::correctTime(std::string input){
	std::istringstream in(input);
	int hour;
	int mins;

	char c;

	in >> hour >> c >> mins;

	std::ostringstream out;

	out << hour << COLON1 << (mins<10 ? ZERO_STRING : QUOTE) << mins;
	return out.str();
}



//@author A0100617W
bool TimeParser::checkHour12(int hour){
	if(hour < 0){
		return false;
	}else if(hour >= 12){
		return false;
	}else{
		return true;
	}
}

bool TimeParser::checkHour24(int hour){
	if(hour < 0){
		return false;
	}else if(hour >= 24){
		return false;
	}else{
		return true;
	}
}


//@author A0100617W
bool TimeParser::checkMin(int min){
	if(min < 0){
		return false;
	}else if(min > 59){
		return false;
	}else{
		return true;
	}
}



//@author A0100617W
std::string TimeParser::getStandardTimeString_ampm(std::string input){
	//format: 11 am
	std::string time;
	std::ostringstream out;
	std::istringstream in(input);

	int hours;
	std::string am_pm;
	in >> hours >> am_pm;

	if((am_pm[0] == 'p')||(am_pm[0] == 'P')){
		if(hours != 12){
			hours = hours + 12;
		}
	}

	out << hours << COLON1 << DOUBLE_ZERO;

	time = out.str();
	return time;
}




//@author A0100617W
std::string TimeParser::getStandardTimeString_column_ampm(std::string input){
	//format: 11:11 am
	std::string time;
	std::ostringstream out;
	std::istringstream in(input);
	int hours;
	int mins;
	char column;
	std::string am_pm;
	in >> hours >> column >> mins >> am_pm;

	if((am_pm[0] == 'p')||(am_pm[0] == 'P')){
		if(hours != 12){
			hours = hours + 12;
		}
	}

	if(mins < 10){
		out << hours << COLON_ZERO << mins;
	}else{
		out << hours << COLON1 << mins;
	}

	time = out.str();
	return time;


}


//@author A0100617W
std::string TimeParser::getStandardTimeString_column(std::string input){
	//format: 11:11
	std::string time;
	std::ostringstream out;

	std::istringstream in(input);

	int hours;
	int mins;
	char column;
	in >> hours >> column >> mins;


	if(mins < 10){
		out << hours << COLON_ZERO << mins;
	}else{
		out << hours << COLON1 << mins;
	}

	time = out.str();
	return time;

}


//@author A0100617W
//catch the first match of input string that matches to a time format. 
//Get the start and end positions('startPos', 'endPos') of the match in input string and the standardized time string('time').
//a time format can be:  10:10 am, 10 am, 10:00

bool TimeParser::parse(std::string input, std::string& time, size_t& startPos, size_t& endPos){

	std::ostringstream out;
	std:: smatch match;
	if(std::regex_search(input, match, column_ampm)){
		//format:   10  : 00   am
		startPos = match.position();
		endPos = match.position() + match.length() - 1;
		std::string rawTime = match.str();
		time = getStandardTimeString_column_ampm(rawTime);

		return true;


	}else if(std::regex_search(input, match, ampm)){
		//format:   10   am

		startPos = match.position();
		endPos = match.position() + match.length() - 1;
		std::string rawTime = match.str();
		time = getStandardTimeString_ampm(rawTime);

		return true;


	}else if(std::regex_search(input, match, column)){
		//format:   10  : 00   

		startPos = match.position();
		endPos = match.position() + match.length() - 1;
		std::string rawTime = match.str();
		time = getStandardTimeString_column(rawTime);

		return true;
	}

	return false;
}


//@author A0100617W
//catch the first match of input string that matches to a Twoime format. 
//Get the start and end positions('startPos', 'endPos') of the match in input string and two standardized time strings('timeS' and 'timeE').
//a time format can be:  10:10 am, 10 am, 10:00

bool TimeParser::parseTwoTime(std::string input, std::string& timeS, std::string& timeE, size_t& stPos, size_t& edPos){
	//format 10-12
	std::smatch match;
	char c;
	int hourS;
	int hourE;

	if(std::regex_search(input, match, num_num)){               
		stPos = match.position();                        //get the position of match and standard time string
		edPos = match.position() + match.length() - 1;
		input = match.str();
		std::istringstream in(input);

		in >> hourS >> c >> hourE;

		timeS = std::to_string(hourS) + COLON_DOUBLE_ZERO;
		timeE = std::to_string(hourE) + COLON_DOUBLE_ZERO;
		timeS = correctTime(timeS);
		timeE = correctTime(timeE);
		return true;

	}
	return false;
}



